/**
 * 基于axios的数据请求mixin
 * 便于各组件复用数据请求相关代码
 */
export default {
    data () {
        return {
            // 安全请求锁
            safeRequestLock: [],
            // 安全请求对象
            safeRequestPromise: {},
        }
    },
    methods: {
        // 安全请求
        async safeRequestFunc (setting = {}) {
            try {
                let safeKey = setting.id || setting.url
                if (!this.safeRequestPromise.hasOwnProperty(safeKey)) {
                    console.log('[safeRequestFunc]#未在请求队列', safeKey)
                    this.safeRequestPromise[safeKey] = []
                }
                return new Promise(async (resolve, reject) => {
                    // 推入队列
                    this.safeRequestPromise[safeKey].push({
                        resolve,
                        reject
                    })
                    if (this.safeRequestLock.indexOf(safeKey) === -1) {
                        console.log('[safeRequestFunc]#请求加锁', safeKey, setting)
                        // 加锁
                        this.safeRequestLock.push(safeKey)
                        let [apiError, apiResult] = await this.requestFunc(setting)
                        console.log('[safeRequestFunc]#请求结果', apiError, apiResult)
                        // 批量处理
                        if (this.safeRequestPromise[safeKey].length) {
                            while (this.safeRequestPromise[safeKey].length) {
                                this.safeRequestPromise[safeKey].shift().resolve([apiError, apiResult])
                            }
                        }
                        // 解锁
                        let lockIndex = this.safeRequestLock.indexOf(safeKey)
                        if (lockIndex !== -1) {
                            this.safeRequestLock.splice(lockIndex, 1)
                        }
                    }
                })
            } catch (exception) {
                console.log('[safeRequestFunc]#异常', exception)
                return Promise.resolve([exception.message || '[safeRequestFunc]#异常', null])
            }
        },
        // 请求方法
        async requestFunc (setting = {}) {
            try {
                // region 创建axios实例
                // 请求取消控制
                let cancelController = new window.AbortController()
                let cancelSignal = cancelController.signal
                // 通过token取消[兼容代码]
                // eslint-disable-next-line no-undef
                let cancelSource = $GP.Server.axios.CancelToken.source()
                // eslint-disable-next-line no-undef
                let axiosObject = $GP.Server.axios.create({
                    // 请求基址
                    baseURL: this.API_BASE || '',
                    // 请求头
                    headers: {
                        'X-Requested-With': 'XMLHttpRequest',
                        'Accept': 'application/json',
                        'Content-Type': 'application/json',
                    },
                    signal: cancelSignal, // 取消信号
                    cancelToken: cancelSource.token, // 取消token[兼容代码]
                    cancelRequest: false, // 取消请求
                    loginAuth: false, // 登陆认证
                })
                // endregion
                // region 请求拦截器
                axiosObject.interceptors.request.use(async (config) => {
                    console.log('[requestFunc]#请求拦截器', config)
                    if (setting.interceptorsRequest) {
                        let resultArray = await this.onCallExecute(setting.interceptorsRequest, {config, setting})
                        if (resultArray.length) {
                            console.log('[requestFunc]#请求拦截调用结果', resultArray)
                            config = resultArray[resultArray.length - 1].result
                        }
                    }
                    if (config.cancelRequest) {
                        console.log('[requestFunc]#取消请求')
                        // 取消请求
                        cancelSource.cancel('请求取消')
                        cancelController.abort()
                    }
                    return config
                }, (error) => {
                    console.log('[requestFunc]#请求拦截出错', error)
                })
                // endregion
                // region 响应拦截器
                axiosObject.interceptors.response.use(async (response) => {
                    console.log('[requestFunc]#响应拦截器', response)
                    if (setting.interceptorsResponse) {
                        // 方法调用结果
                        let resultArray = await this.onCallExecute(setting.interceptorsResponse, {response, setting})
                        if (resultArray.length) {
                            console.log('[requestFunc]#响应拦截调用结果', resultArray)
                            return resultArray[resultArray.length - 1].result
                        }
                    }
                    return response
                })
                // endregion
                console.log('[requestFunc]#发起请求', setting)
                // eslint-disable-next-line no-undef
                let [apiError, apiResult] = await axiosObject.request(setting).then((response) => {
                    console.log('[requestFunc]#请求响应', response)
                    if (response.status == 200) {
                        if (response.data.code !== 1) {
                            if (response.data.data && (typeof response.data.data === 'string') && response.data.data.includes('@')) {
                                // 发布事件
                                window.EMA.fire(response.data.data)
                            }
                        }
                        return [null, response.data]
                    }
                    return [response.statusText, null]
                }).catch((exception) => {
                    console.log('[axiosObject.request]#异常', exception)
                    return [exception.message, null]
                })
                console.log('[requestFunc]#请求结果', apiError, apiResult)
                return Promise.resolve([apiError, apiResult])
            } catch (exception) {
                console.log('[requestFunc]#异常', exception)
                return Promise.resolve([exception.message || '[requestFunc]#异常', null])
            }
        },
    }
}
